#include "glwidget.h"

#if defined(Q_OS_MAC)
#include <OpenGL.h>
#endif

GLWidget::GLWidget(QWidget *parent) :
    QGLWidget(parent),
    timer(new QBasicTimer)
{

    setAttribute(Qt::WA_PaintOnScreen);
    setAttribute(Qt::WA_NoSystemBackground);
    setAutoBufferSwap(false);
    model = new Model(Sbs2Common::getRootAppPath() + QString("vertface_brain_reduced.obj"));
    sourceRecOn = 0;

    dragX = dragY = 0;
    gyroX = gyroY = 0;
    dragging = 0;

    logoPixmap.load(":/dtu.jpg");
    infoPressed = 0;

    resetFreqs();
    changeFrequency("alpha");

}

void GLWidget::changeFrequency(QString name)
{
    resetFreqs();
    if (name.compare("delta") == 0)
    {
        deltaOn = 1;
    }
    if (name.compare("theta") == 0)
    {
        thetaOn = 1;
    }
    if (name.compare("alpha") == 0)
    {
        alphaOn = 1;
    }
    if (name.compare("lowBeta") == 0)
    {
        lowBetaOn = 1;
    }
    if (name.compare("beta") == 0)
    {
        betaOn = 1;
    }


    emit changeBand(name);
}

void GLWidget::resetFreqs()
{
    deltaOn = 0;
    thetaOn = 0;
    alphaOn = 0;
    lowBetaOn = 0;
    betaOn = 0;

}

void GLWidget::quit()
{
    timer->stop();
}

void GLWidget::resizeGL(int w, int h)
{
    aspectRatio = (qreal) w / (qreal) h;
    quitRect = QRect(w-20-80,20,80,80);
    toggleRect = QRect(20,20,180,80);
    toggleRectEmocap = QRect(220,20,180,80);

    //frequency buttons
    int buttonWidth = 180;
    int buttonWMargin = -20;
    deltaRect = QRect(buttonWMargin,120, buttonWidth, 60);
    thetaRect = QRect(buttonWMargin,120 + 60 + 10, buttonWidth, 60);
    alphaRect = QRect(buttonWMargin,120+2*(60+10), buttonWidth, 60);
    lowBetaRect = QRect(buttonWMargin,120+3*(60+10), buttonWidth, 60);
    betaRect = QRect(buttonWMargin,120+4*(60+10), buttonWidth, 60);
    logoRect = QRect(w - logoPixmap.width() - 10, h - logoPixmap.height() - 10,logoPixmap.width(), logoPixmap.height());
    infoRect = QRect(w/2 - 500, h/2 - 320, 1000, 640);
    websiteRect = QRect(w - logoPixmap.width() - 1200, h  - 80, 800, 80);

}

void GLWidget::initializeGL()
{
#if defined(Q_OS_MAC)
    const GLint swapInterval = 1;
    CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &swapInterval);
#endif

    glClearColor(0.f, 0.0f, 0.0f, 1.0f);
    camera = QVector3D(0, -50, 20);
    dragX = 0;
    model->setFragmentShaderFile(QString(":/fshader.normals.glsl"));
    model->setVertexShaderFile(QString(":/vshader.normals.glsl"));
    model->linkShaderProgram();
    model->initShaderProgram();

    timer->start(20, this);

}

void GLWidget::paintGL()
{

    QPainter painter;
    painter.begin(this);

    painter.beginNativePainting();


    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glFrontFace(GL_CW);
    glCullFace(GL_FRONT);
    glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);
    /* Disable for opaque colors. */
    glEnable(GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);



    mainModelView = QMatrix4x4(); // reset
    mainModelView.perspective(45.0, aspectRatio, 1.0, 400.0);
    mainModelView.lookAt(camera,QVector3D(0,0,0),QVector3D(0.0,1.0,0.0));

    mainModelView.translate(0,-1,0);


    dragX += gyroX * 0.008 * (1-dragging);
    dragY += gyroY * 0.008 * (1-dragging);

    mainModelView.rotate(dragY,1,0,0);
    mainModelView.rotate(dragX,0,0,1);

    mainModelView.rotate(180,0.0,0.0,1.0);
    mainModelView.translate(0,1,0);
    mainModelView.scale(1/4.5);


    model->draw(mainModelView);

    glDisable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);
    glDisable(GL_BLEND);

    painter.endNativePainting();


    //Onscreen control
    painter.fillRect(quitRect,QColor(255,0,0,20));
    painter.drawRect(quitRect);

    if (sourceRecOn == 0)
    {
        painter.setFont(QFont("helvetica",8));
        painter.setPen(QColor("white"));
        painter.fillRect(toggleRect,QColor(0,255*sourceRecOn,255*(1-sourceRecOn),120));
        painter.fillRect(toggleRectEmocap,QColor(0,255*sourceRecOn,255*(1-sourceRecOn),120));
        painter.drawText(toggleRect, Qt::AlignCenter, "emotiv");
        painter.drawText(toggleRectEmocap, Qt::AlignCenter, "emocap");
    }


    painter.setFont(QFont("helvetica",8));
    painter.setPen(QColor("white"));
    painter.fillRect(deltaRect,QColor(255*(1-deltaOn),255*deltaOn,0,20+40*deltaOn));
    painter.drawText(deltaRect,Qt::AlignCenter,"1-4Hz"); //delta

    painter.fillRect(thetaRect,QColor(255*(1-thetaOn),255*thetaOn,0,20+40*thetaOn));
    painter.drawText(thetaRect,Qt::AlignCenter,"4-8Hz"); //theta

    painter.fillRect(alphaRect,QColor(255*(1-alphaOn),255*alphaOn,0,20+40*alphaOn));
    painter.drawText(alphaRect,Qt::AlignCenter,"8-12Hz"); //alpha

    painter.fillRect(lowBetaRect,QColor(255*(1-lowBetaOn),255*lowBetaOn,0,20+40*lowBetaOn));
    painter.drawText(lowBetaRect,Qt::AlignCenter,"12-16Hz"); //low beta

    painter.fillRect(betaRect,QColor(255*(1-betaOn),255*betaOn,0,20+40*betaOn));
    painter.drawText(betaRect,Qt::AlignCenter,"16-20Hz"); //beta



    painter.drawPixmap(logoRect, logoPixmap);
    painter.setPen(QColor("gray"));
    painter.setFont(QFont("helvetica",9));
    painter.drawText(websiteRect,QString("code.google.com/p/SmartphoneBrainScanner2"));


    if (infoPressed)
    {
        painter.fillRect(infoRect,QColor(0,0,0,180));
        painter.drawRect(infoRect);
        painter.drawText(infoRect,Qt::AlignCenter, QString("Technical University of Denmark \n\n SmartphoneBrainScanner2 \n\n Jakob Eg Larsen, jel@imm.dtu.dk \n Arkadiusz Stopczynski, arks@imm.dtu.dk \n Carsten Stahlhut, cs@imm.dtu.dk \n Michael Kai Petersen, mkp@imm.dtu.dk \n Lars Kai Hansen, lkh@imm.dtu.dk"));
    }

    painter.end();
    swapBuffers();

}

void GLWidget::mousePressEvent(QMouseEvent* event)
{
    if (event->button() == Qt::LeftButton)
    {
        if (quitRect.contains(event->pos()))
            QApplication::quit();

        if (toggleRect.contains(event->pos()))
        {
            if (sourceRecOn)
            {

            }
            else
            {
                sourceRecOn = 1;
#ifdef Q_WS_MAEMO_5
                emit turnSourceReconstructionPowerOn(128,32,8*1,8*60, "emotiv");
#else
                emit turnSourceReconstructionPowerOn(128,16,8*1,8*30, QString("emotiv"));
#endif

            }
        }
        if (toggleRectEmocap.contains(event->pos()))
        {
            if (sourceRecOn)
            {

            }
            else
            {
                sourceRecOn = 1;
#ifdef Q_WS_MAEMO_5
                emit turnSourceReconstructionPowerOn(128,32,8*1,8*60, "emocap");
#else
                emit turnSourceReconstructionPowerOn(128,16,8*1,8*30, QString("emocap"));
#endif

            }

        }

        if (deltaRect.contains(event->pos()))
            changeFrequency("delta");
        if (thetaRect.contains(event->pos()))
            changeFrequency("theta");
        if (alphaRect.contains(event->pos()))
            changeFrequency("alpha");
        if (lowBetaRect.contains(event->pos()))
            changeFrequency("lowBeta");
        if (betaRect.contains(event->pos()))
            changeFrequency("beta");
        if (logoRect.contains(event->pos()))
            infoPressed = !infoPressed;
        if (infoRect.contains(event->pos()))
            infoPressed = 0;

        dragLastPosition = dragStartPosition = event->pos();
    }
}

void GLWidget::mouseMoveEvent(QMouseEvent* event)
{
    if(!(event->buttons() & Qt::LeftButton))
        return;

    if(dragging)
    {

        dragX -= (dragLastPosition.x() - event->pos().x())/2.0;
        dragY -= (dragLastPosition.y() - event->pos().y())/2.0;
    }
    dragLastPosition = event->pos();
    dragging = true;

}

void GLWidget::mouseReleaseEvent(QMouseEvent* event)
{
    dragging = false;
}


void GLWidget::timerEvent(QTimerEvent *e)
{
    updateGL();
}

void GLWidget::updateColorForVertex(int vertex, double r, double g, double b, double a)
{
    model->updateColorForVertex(vertex, r, g, b, a);
}

void GLWidget::updateGyroX(double gyroX_)
{
    gyroX = gyroX_;
    if (abs(gyroX - 1660) < 5) gyroX = 1660;
    gyroX -= 1660;
}

void GLWidget::updateGyroY(double gyroY_)
{
    gyroY = gyroY_;
    if (abs(gyroY - 1660) < 5) gyroY = 1660;
    gyroY -= 1660;
}
